package stubcall

import (
	"sync/atomic"
)

var (
	stubCallID uint32
)

//@title stubcall 管理器
type SrvStubCallMgr struct {
	callmap  map[uint32]*SrvStubCall
	delQueue chan uint32
}

func NewSrvStubCallMgr() *SrvStubCallMgr {
	srv := &SrvStubCallMgr{
		callmap:  make(map[uint32]*SrvStubCall),
		delQueue: make(chan uint32, 16),
	}
	return srv
}

func (scm *SrvStubCallMgr) GetCall(callid uint32) *SrvStubCall {
	if scm == nil {
		return nil
	}
	if st, ok := scm.callmap[callid]; ok {
		return st
	}
	//TODO 添加日志
	return nil
}

func (scm *SrvStubCallMgr) AddCall(call *SrvStubCall) bool {
	//TODO check stubcall 合法性
	if call == nil {
		return false
	}
	call.serviceCallID = atomic.AddUint32(&stubCallID, 1)
	if _, ok := scm.callmap[call.serviceCallID]; ok {
		return false
	}
	scm.callmap[call.serviceCallID] = call
	return true
}

func (scm *SrvStubCallMgr) DestroyCall(callid uint32) {
	if scm == nil {
		return
	}
	scm.delQueue <- callid
}

func (scm *SrvStubCallMgr) cleanUp() {
	scm.callmap = make(map[uint32]*SrvStubCall)
}

func (scm *SrvStubCallMgr) Tick() {
	for {
		select {
		case callid := <-scm.delQueue:
			delete(scm.callmap, callid)
		default:
			return
		}
	}
}

//@title 清理一个service实例的所有stubcall
func (scm *SrvStubCallMgr) cleanByServiceID(srv uint32) {
	for key, value := range scm.callmap {
		if value == nil {
			delete(scm.callmap, key)
			continue
		}
		if value.serviceID == srv {
			delete(scm.callmap, key)
		}
	}
}
